package org.grayrabbit.cms.action.common;

import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.grayrabbit.cms.constant.ConstantOperCode;
import org.grayrabbit.cms.constant.ConstantWebApp;
import org.grayrabbit.cms.constant.DBInitId;
import org.grayrabbit.cms.constant.DictionaryStaticValues;
import org.grayrabbit.cms.entity.Admin;
import org.grayrabbit.cms.entity.AdminOperRela;
import org.grayrabbit.cms.entity.Category;
import org.grayrabbit.cms.entity.Content;
import org.grayrabbit.cms.entity.OperCode;
import org.grayrabbit.cms.entity.Site;
import org.grayrabbit.cms.entity.Topic;
import org.grayrabbit.cms.service.category.CategoryService;
import org.grayrabbit.cms.service.content.ContentService;
import org.grayrabbit.cms.service.dictionary.DictionaryService;
import org.grayrabbit.cms.service.site.SiteService;
import org.grayrabbit.cms.service.system.AdminOperRelaService;
import org.grayrabbit.cms.service.system.OperCodeService;
import org.grayrabbit.cms.service.system.OperLogService;
import org.grayrabbit.cms.service.topic.TopicService;
import org.grayrabbit.cms.util.DateUtil;
import org.grayrabbit.cms.util.FilePathSptUtil;
import org.grayrabbit.cms.util.IpUtil;
import org.grayrabbit.cms.vo.system.OperCodeCheckBean;
import org.grayrabbit.web.struts2.GenericAction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public abstract class BaseAction<T> extends GenericAction<T> {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	public static final String TOPIC = "topic";
	private String root = FilePathSptUtil.STATIC_RESOURCES_URL;
	public static final String JUMP_FLAG = "jump_flag";
	private String cms_url;
	protected Site currentMainSite;
	protected List<Content> linkLists;

	public String getRoot() {
		return root;
	}

	public void setRoot(String root) {
		this.root = root;
	}

	@Autowired
	@Qualifier("dictionaryServiceImpl")
	protected DictionaryService dictionaryService;
	@Autowired
	protected OperLogService operLogService;
	protected String uploadUrl;
	
	@Autowired
	@Qualifier("categoryServiceImpl")
	private CategoryService categoryService;
	
	@Autowired
	@Qualifier("topicServiceImpl")
	private TopicService topicService;
	
	@Autowired
	@Qualifier("adminOperRelaServiceImpl")
	private AdminOperRelaService adminOperRelaService;
	
	@Autowired
	@Qualifier("operCodeServiceImpl")
	private OperCodeService operCodeService;
	
	@Autowired
	@Qualifier("siteServiceImpl")
	private SiteService siteService;
 
	@Autowired
	@Qualifier("contentServiceImpl")
	private ContentService contentService;
	
	/***
	 * 
	 * 添加日志信息
	 * @param module 模块名称
	 * @param act  动作
	 * @param ObjectId  操作对象ID
	 */
	public void addLog(String module ,String act,String ObjectId){
		Admin admin  = (Admin)getSessionValue(ConstantWebApp.CURRENT_ADMIN);		 
	   operLogService.addLog(admin.getLoginName(), 
					admin.getRealName(), module, act, 
					ObjectId, IpUtil.getClientIp(getRequest()));
 
	}
	
	/***
	 * 
	 * 添加日志信息
	 * @param module 模块名称
	 * @param act  动作
	 * @param ObjectId  操作对象ID
	 * @param memo  备注
	 */
	public void addLog(String module ,String act,String objectId,String memo){
	   Admin admin  = (Admin)getSessionValue(ConstantWebApp.CURRENT_ADMIN);		 
	   operLogService.addLog(admin.getLoginName(), 
					admin.getRealName(), module, act, 
					objectId, memo,IpUtil.getClientIp(getRequest()));
	}
	
	/**
	 * 获取数据字典KEY值对应的NAME
	 * 
	 * @param key
	 * @param type
	 *            数据字典类型
	 * @return
	 */
	public String getName(String key,String code) {
		return dictionaryService.getDictionaryByDictionaryKey(key,code).getDictionaryValue();
	}

	public String getEtpType(String typeCode){
		return dictionaryService.getDictionaryByDictionaryKey(typeCode,DictionaryStaticValues.ENTERPRISE_TYPE).getDictionaryValue();
	}
	
	public String getUploadUrl() {
		return FilePathSptUtil.UPLOAD_URL;
	}
	
	/** （站点、栏目、专题）节点权限判断
	 * @param operId  ID
	 * @param targetId 
	 * @return  true 通行 false 拦截到权限提示页面（AUTH_FAILURE_PAGE） 
	 */
	public boolean authLicence(String authCode, String targetId) {
		if(isSupperAdmin())
			return true;
		if(StringUtils.isNotBlank(targetId) && StringUtils.isNotBlank(authCode)){			
			 return authLicenceCheck(authCode,"-"+targetId);
		}
		return false;
	}
	
	/** 全局节点权限判断
	 * @param operId
	 * @return true 通行 false 拦截到权限提示页面（AUTH_FAILURE_PAGE） 
	 */
	public boolean authLicence(String operCode) {
		if(isSupperAdmin())
			return true;
		if(StringUtils.isNotBlank(operCode)){			
			 return authLicenceCheck(operCode,"-authority");
		}
		return false;
	}
	
	/**  对像级别的权限，拥有某一对象权限时，功能按钮允许通行
	 */
	public boolean authLicenceLike(String authCode) {
		if(isSupperAdmin())
			return true;
		if( StringUtils.isNotBlank(authCode)){	
			String[] codes = authCode.split(",");
			for(String code :codes){
				code +="-" ;
				Set<String> set = getAuthSet();
				for(String s:set){
					if(s.startsWith(code)) return true;
				} 
			}
			 
		}
		return false;
	}
	
	/**
	 *  判断处理，是否具有权限
	 * @param authCode
	 * @return
	 */
	private boolean authLicenceCheck(String authCodes,String targetId){ 
		if(isSupperAdmin())
			return true;
		Set<String> set = getAuthSet();
		if(StringUtils.isNotBlank(authCodes)&& !set.isEmpty()){ 
			String[] codes = authCodes.split(",");
			for(String s :codes){
				if(set.contains(s+targetId))
					return true;
			} 			
		}
		return false;
	} 
	 
	/**
	 * 当前登陆管理员权限集合
	 * @return 
	 */
	@SuppressWarnings("unchecked")
	public HashSet<String>  getAuthSet(){		
		Object obj = getSessionValue(ConstantWebApp.CURRENT_ADMIN_AUTH_CODE);
		if(obj != null && obj instanceof HashSet ){
			return (HashSet<String>)obj;
		}
		return new HashSet<String>();
	}

	public String getCurrentAdminId() {
		Object obj = getSessionValue(ConstantWebApp.CURRENT_ADMIN_ID);
		String id = obj==null?null:(String)obj;
		return id;
	}
	
	/**lefttree对象权限判断：对象不确定*/
	public boolean  authLicenceLikeSite(String codes){
		if(isSupperAdmin())
			return true;
		if(StringUtils.isBlank(codes))  return false;
		String[] cs = codes.split(",");
		Set<String> set = getAuthSet();
		if(set.isEmpty())  return false;
	 
		for(String code :cs){
			for(String s : set){
				if(s.startsWith(code+"-")){
					String targetId = s.replace(code+"-", "");
					if(StringUtils.isNotBlank(targetId) && checkTargetId(code,targetId)){ 
						return true;
					}
				} 
			} 
		}
		return false;
	}
	
	private boolean checkTargetId(String code,String targetId){
		if(code.startsWith(ConstantOperCode.GOBLE_FLAG)){
			return true;
		}else if(code.startsWith(ConstantOperCode.SITE_FLAG)){
			if(targetId.equals(getCurrentSiteId()))  return true;			
		}else if(code.startsWith(ConstantOperCode.CAT_FLAG)){
			Category  c = categoryService.findCatById(targetId);
			if(c!=null && c.getSite() != null && c.getSite().getSiteId()!=null 
					&& getCurrentSiteId()!=null && getCurrentSiteId().equals( c.getSite().getSiteId())){
				return true;
			}
		}else if(code.startsWith(ConstantOperCode.TOPIC_FLAG)){
			Topic  c = topicService.getTopic(targetId);
			if(c!=null && c.getSite() != null && c.getSite().getSiteId()!=null 
					&& getCurrentSiteId()!=null && getCurrentSiteId().equals( c.getSite().getSiteId())){
				return true;
			}
		}
		return false;
	}
	private boolean isSupperAdmin(){
		if(DBInitId.CMS_SUPPER_ADMIN_ID.equals(getCurrentAdminId())) 
			return true;
		return false;
	}
	public String getCurrentSiteId() {
		Object obj = getSessionValue(ConstantWebApp.CURRENT_SITE);
		String id = obj==null?null:((Site)obj).getSiteId();
		return id;
	}
	/**
	 * 从session中获得登陆信息
	 * @return
	 */
	public Admin getCurrentAdmin(){
		 Object obj =  getSessionValue(ConstantWebApp.CURRENT_ADMIN);
		 Admin admin = null;
		 if(obj != null && obj instanceof Admin){
			 admin = (Admin)obj;			 
		 }
		 return admin;
	}
	/**
	 *  新增站点、栏目、专题时，给操作人赋予相应权限
	 */
	public void addObjectDistributeAuthCode(String operTargetId,String operTargetType,String operCode){
		Admin admin = getCurrentAdmin();
		if(admin == null || DBInitId.CMS_SUPPER_ADMIN_ID.equals(admin.getAdminId()) ) return ;
		OperCode oc = operCodeService.findByCode(operCode);
		if(oc==null || StringUtils.isBlank(oc.getOperId())) return ;
		AdminOperRela adminOperRela = new AdminOperRela();
		adminOperRela.setAdmin(getCurrentAdmin());
		adminOperRela.setOperTargetId(operTargetId);
		adminOperRela.setOperTargetType(operTargetType);
		adminOperRela.setOperCode(oc);
		adminOperRelaService.addObjectDistributeAuthCode(adminOperRela); 
		reloadAuthCode(operTargetId, operCode);
		 
		 
	}
	/**
	 * 设置审核人时，赋予审核人相应的审核权限
	 */
	public void distributeAuditAuthCode(String operTargetId,String operTargetType,String operCode,String auditNames){
		OperCode oc = operCodeService.findByCode(operCode);
		if(oc==null || StringUtils.isBlank(oc.getOperId())) return ;		
		AdminOperRela adminOperRela = new AdminOperRela();
		adminOperRela.setOperTargetId(operTargetId);
		adminOperRela.setOperTargetType(operTargetType);
		adminOperRela.setOperCode(oc);
		adminOperRelaService.distributeAuditAuthCode(adminOperRela,auditNames);
	 
	} 
	
	public String formatDate(Date date){
		return DateUtil.formatDateToString(date, "yyyy-MM-dd HH:mm");
	}
	
	/**
	 * 新增站点、栏目、专题时，赋予相应权限后，  即时刷新SESSION权限
	 */
	public void reloadAuthCode(String operTargetId,String operCode){
		Admin admin = getCurrentAdmin();
		if(admin == null 
				|| DBInitId.CMS_SUPPER_ADMIN_ID.equals(admin.getAdminId()) ) 
			return ;
		Set<String> set = getAuthSet();
		set.add(operCode+"-"+operTargetId); 
		setSessionValue(ConstantWebApp.CURRENT_ADMIN_AUTH_CODE,set);
	}
	
 
	/**
	 *  实现AuthCheckAction接口的action类的在其实现方法调用该方法。
	 *   通过该方法加载相关的权限验证信息
	 * @param list
	 * @param operKey ：  action 类型key 比如：某一个action及用于新建 右用于更新
	 * @param operValue
	 * @param paramKey  ：操作对象 targetId key（变量名）
	 * @param paramValue
	 * @param operCode  ：操作权限码 
	 * @param operType	：操作权限类型
	 */
	protected  void loadAuthCheckInfo(List<OperCodeCheckBean> list ,
			String operKey, Object operValue, String paramKey,
			String paramValue, String operCode, String operType){
		if(StringUtils.isBlank(operType))
			throw new IllegalArgumentException("operType can't be blank !"); 
		OperCodeCheckBean bean = new OperCodeCheckBean(operKey, operValue, paramKey, 
				paramValue, operCode, operType);
		list.add(bean);
	}

	
	public Site getCurrentMainSite() {
		if(currentMainSite==null){
			String siteId = FilePathSptUtil.MAIN_SITE_ID;
			currentMainSite= siteService.getSite(siteId);
		}
		return currentMainSite;
	}

	public void setSite(Site site) {
		this.currentMainSite = site;
	}

	public String getCms_url() {
		cms_url = FilePathSptUtil.CMS_VISIT_CONTEXT_PATH;
		return cms_url;
	}

	public void setCms_url(String cms_url) {
		this.cms_url = cms_url;
	}

	public List<Content> getLinkLists() {
		long[] num = {0L,Long.parseLong(FilePathSptUtil.LINK_NUM)};
		linkLists = contentService.ftlFindAll(null,null,null,null, null, new String[]{"ff8080813096a0b50130975ba87b0044"}, new String[]{"LinkContent"}, null, null, null, null, null, num, false, 10, 1);
		return linkLists;
	}

	public void setLinkLists(List<Content> linkLists) {
		this.linkLists = linkLists;
	}

}
